package cn.cxyxj.study.webflux03.utils;

import cn.cxyxj.study.webflux03.entity.SysUserDetails;
import cn.hutool.core.lang.Assert;
import cn.hutool.json.JSONObject;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTPayload;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author cxyxj
 */
public class JWTUtil {
    /**
     *  应用密钥
     */
    public static final String APPSECRET_KEY = "cxyxj_awesome";
    
    public static final String JTI = "jti";

    public static final String USERNAME = "USERNAME";

    public static final String USERID = "USERID";

    /**
     * 生成token
     */
    private static String generateToken(Map<String, Object> claims) {
        return cn.hutool.jwt.JWTUtil.createToken(claims, APPSECRET_KEY.getBytes());
    }

    /**
     * 根据userDetails设置有效载荷信息
     */
    public static String generateToken(SysUserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>(2);
        claims.put(USERNAME, userDetails.getUsername());
        claims.put(USERID, userDetails.getSysUser().getId());
        claims.put(JTI,UUID.randomUUID().toString().replace("-",""));
        return generateToken(claims);
    }

    /**
     * 有七个默认字段供选择
     * {
     * 	"iss"：发行人
     * 	"exp"：到期时间
     * 	"sub"：主题
     * 	"aud"：用户
     * 	"nbf"：在此之前不可用
     * 	"iat"：发布时间
     * 	"jti"：JWT ID用于标识该JWT
     * }
     */
    public static String generateToken(SysUserDetails userDetails,String uuidStr) {
        Map<String, Object> claims = new HashMap<>(2);
        claims.put(USERNAME, userDetails.getUsername());
        claims.put(USERID, userDetails.getSysUser().getId());
        claims.put(JTI,uuidStr);
        return generateToken(claims);
    }

    /**
     * Token的解析
     *
     * @param token
     * @return
     */
    public static JWT parseJWT(String token) {
        // 先验证 token 是否由本系统签发
        boolean verify = cn.hutool.jwt.JWTUtil.verify(token, APPSECRET_KEY.getBytes());
        if(!verify){
           throw new IllegalArgumentException("该 token 异常");
        }
        return cn.hutool.jwt.JWTUtil.parseToken(token);
    }

    public static void main(String[] args) {
        Map<String, Object> claims = new HashMap<>(2);
        claims.put("USERNAME", "cxyxj");
        claims.put("USERID", "1");
        claims.put("jti",UUID.randomUUID().toString().replace("-",""));
        String token = cn.hutool.jwt.JWTUtil.createToken(claims, APPSECRET_KEY.getBytes());
        System.out.println(token);
        JWT jwt = cn.hutool.jwt.JWTUtil.parseToken(token);
        JWTPayload payload = jwt.getPayload();
        JSONObject claimsJson = payload.getClaimsJson();
        System.out.println(payload.getClaim("jti"));
        System.out.println(claimsJson);
        System.out.println(cn.hutool.jwt.JWTUtil.verify(token, APPSECRET_KEY.getBytes()));
    }
}

